#!/usr/bin/env python3
###
# @Author: Logan.Li
# @Gitee: https://gitee.com/attacker
# @email: admin@attacker.club
# @Date: 2025-03-14 11:10:30
# @LastEditTime: 2025-03-14 11:10:35
# @Description: 告警处理模块
###

import json
import logging
from typing import Dict, List
from datetime import datetime
from .alert_suppression import AlertSuppression

class AlertHandler:
    """告警处理器"""
    
    def __init__(self, config: Dict):
        """初始化告警处理器
        
        Args:
            config: 配置信息
        """
        self.config = config
        # 初始化告警抑制器
        self.suppression = AlertSuppression(config.get('redis', {}))
        
    def _check_threshold(self, metric: Dict, value: float) -> bool:
        """检查是否超过阈值
        
        Args:
            metric: 指标定义
            value: 当前值
        """
        threshold = metric.get('threshold')
        if threshold is None:
            return False
            
        # 根据单位判断比较方式
        unit = metric.get('unit', '')
        if unit in ['percent', 'count', 'ms']:
            return value > threshold
        elif unit == 'status':
            return value == threshold  # 状态匹配则告警
        return False
        
    def _get_alert_priority(self, metric: Dict, value: float) -> str:
        """获取告警优先级
        
        Args:
            metric: 指标定义
            value: 当前值
        """
        base_priority = metric.get('priority', 'warning')
        threshold = metric.get('threshold')
        
        if threshold is None:
            return base_priority
            
        # 根据超出阈值程度提升优先级
        if base_priority == 'warning':
            if value > threshold * 1.5:  # 超出50%
                return 'critical'
        return base_priority
        
    def handle_alert(self, resource: Dict, metric: Dict, value: float) -> None:
        """处理告警
        
        Args:
            resource: 资源信息
            metric: 指标定义
            value: 当前值
        """
        if not self._check_threshold(metric, value):
            return
            
        # 构建告警信息
        alert = {
            'timestamp': datetime.now().isoformat(),
            'platform': resource.get('platform'),
            'resource_type': resource.get('type'),
            'resource_id': resource.get('id'),
            'resource_name': resource.get('name'),
            'metric': metric.get('name'),
            'description': metric.get('description'),
            'value': value,
            'threshold': metric.get('threshold'),
            'unit': metric.get('unit'),
            'alert_type': self._get_alert_priority(metric, value)
        }
        
        # 检查是否需要抑制
        if self.suppression.should_suppress(alert):
            logging.info(f"告警已抑制: {alert['resource_id']} - {alert['metric']}")
            return
            
        # 记录告警
        self.suppression.record_alert(alert)
        
        # 获取之前的告警次数
        alert['previous_count'] = self.suppression.get_alert_count(alert)
        
        # 根据优先级处理告警
        if alert['alert_type'] == 'critical':
            self._handle_critical_alert(alert)
        else:
            self._handle_warning_alert(alert)
            
    def _handle_critical_alert(self, alert: Dict) -> None:
        """处理严重告警
        
        Args:
            alert: 告警信息
        """
        logging.warning(f"严重告警: {alert['resource_id']} - {alert['metric']}")
        # 1. 立即发送通知
        self._send_notification(alert)
        # 2. 记录详细日志
        self._log_alert_details(alert)
        # 3. 可以添加自动处理逻辑
        
    def _handle_warning_alert(self, alert: Dict) -> None:
        """处理警告
        
        Args:
            alert: 告警信息
        """
        logging.info(f"警告: {alert['resource_id']} - {alert['metric']}")
        # 1. 发送通知
        self._send_notification(alert)
        # 2. 记录日志
        self._log_alert_details(alert)
        
    def _send_notification(self, alert: Dict) -> None:
        """发送通知
        
        Args:
            alert: 告警信息
        """
        # 根据告警类型构建消息
        if alert['alert_type'] == 'critical':
            title = f"【严重】{alert['platform']}资源告警"
        else:
            title = f"【警告】{alert['platform']}资源告警"
            
        content = (
            f"时间: {alert['timestamp']}\n"
            f"资源: {alert['resource_name']}({alert['resource_id']})\n"
            f"指标: {alert['description']}\n"
            f"当前值: {alert['value']}{alert['unit']}\n"
            f"阈值: {alert['threshold']}{alert['unit']}\n"
            f"之前告警次数: {alert['previous_count']}"
        )
        
        # 调用通知模块发送告警
        from notification import NotificationManager
        notifier = NotificationManager(self.config.get('notification', {}))
        notifier.send_alert(alert['platform'], title, {
            'resource_id': alert['resource_id'],
            'resource_name': alert['resource_name'],
            'metric': alert['description'],
            'value': alert['value'],
            'threshold': alert['threshold'],
            'message': content
        })
        
    def _log_alert_details(self, alert: Dict) -> None:
        """记录告警详情
        
        Args:
            alert: 告警信息
        """
        logging.info(
            f"告警详情: {json.dumps(alert, ensure_ascii=False, indent=2)}"
        )
